//#pragma once
#include "stdafx.h"
#include <windows.h>
#include <wininet.h>
#include "inetstring.h"

#pragma comment (lib, "wininet.lib")

StringVector SplitString(w_string& strSrc, LPCWSTR lpszDil, BOOL bAddLenZero)
{
	size_t nPosOld = 0;
	size_t nPos = 0;
	size_t nPosDiff = 0;

	StringVector v;
	int nDilLen = lstrlenW(lpszDil);
	while ((nPos = strSrc.find(lpszDil, nPosOld)) != -1)
	{
		nPosDiff = nPos - nPosOld;
		if (nPosDiff > 0 || bAddLenZero)
		{
			w_string tmp = strSrc.substr(nPosOld, nPosDiff);
			v.push_back(tmp);
		}
		nPosOld = nPos + nDilLen;
	}

	nPosDiff = strSrc.length() - nPosOld;
	if (nPosDiff > 0 || bAddLenZero)
		v.push_back(strSrc.substr(nPosOld));

	return v;
}

StringVector SplitString(LPCWSTR lpszSrc, LPCWSTR lpszDil, BOOL bAddLenZero)
{
	w_string strSrc = lpszSrc;
	return SplitString(strSrc, lpszDil, bAddLenZero);
}

DWORD GetResponse(LPCWSTR lpszUserAgent, LPCWSTR lpszUrlToConn, LPWSTR lpszBuffer, DWORD dwChars)
{
	*lpszBuffer = NULL;

	DWORD dwByteRead = 0;

	HINTERNET hSession;
	HINTERNET hUrl;
	hSession = InternetOpenW(lpszUserAgent, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
	if (hSession)
	{
		hUrl = InternetOpenUrlW(hSession, lpszUrlToConn, NULL, 0, 0, 0);
		if (hUrl)
		{
			BOOL bRes;
			LPSTR lpszTmpBufA = new CHAR[dwChars];
			if (lpszTmpBufA)
			{
				//	null terminate string
				bRes = InternetReadFile(hUrl, lpszTmpBufA, dwChars - 1, &dwByteRead);
				if (bRes == TRUE && dwByteRead > 0)
				{
					lpszTmpBufA[dwByteRead] = NULL;
					MultiByteToWideChar(CP_ACP, 0, lpszTmpBufA, -1, lpszBuffer, dwChars);
				}
				delete [] lpszTmpBufA;
			}

			InternetCloseHandle(hUrl);
		}

		InternetCloseHandle(hSession);
	}

	return dwByteRead;
}

LPCWSTR GetFileName(LPCWSTR lpszFullPath)
{
	LPCWSTR lpszRet = wcsrchr(lpszFullPath, L'\\');
	if (lpszRet)
		return lpszRet + 1;
	else
		return lpszFullPath;
}

BOOL GetFilePath(LPCWSTR lpszFullPath, LPWSTR lpszFilePath, DWORD dwChars)
{
	BOOL bRet = FALSE;
	*lpszFilePath = NULL;
	LPCWSTR lpszTmp = wcsrchr(lpszFullPath, L'\\');
	DWORD dwLen = 0;
	if (lpszTmp && (dwLen = lpszTmp - lpszFullPath + 1) <= dwChars)
	{
		lstrcpynW(lpszFilePath, lpszFullPath, dwLen);
		bRet = TRUE;
	}
	return bRet;
}

BOOL GetCurrentPath(LPWSTR lpszCurrPath, DWORD dwChars)
{
	if (GetModuleFileNameW(NULL, lpszCurrPath, dwChars) == 0)
		return FALSE;

	LPWSTR pTmp;
	if ((pTmp = wcsrchr(lpszCurrPath, L'\\')) == NULL)
		return FALSE;
	else
	{
		*pTmp = NULL;
		return TRUE;
	}
}

#pragma comment (lib, "version.lib")

BOOL GetFileVersion(LPCWSTR lpszFileName, DWORD* pdwFileVerMS, DWORD* pdwFileVerLS)
{
	if (lpszFileName == NULL || lstrlenW(lpszFileName) == 0)
		return FALSE;

	DWORD dwHandle = 0;
	DWORD dwVISize = GetFileVersionInfoSizeW(lpszFileName, &dwHandle);
	if (dwVISize == 0)
		return FALSE;

	LPBYTE lpbyteVI = new BYTE[dwVISize];
	if (lpbyteVI == NULL)
		return FALSE;

	BOOL bRet = FALSE;
	if (GetFileVersionInfoW(lpszFileName, 0, dwVISize, lpbyteVI) == TRUE)
	{
		VS_FIXEDFILEINFO* pvsffi;
		UINT uLen = 0;
		if (VerQueryValueW(lpbyteVI, L"\\", (LPVOID*)&pvsffi, &uLen))
		{
			*pdwFileVerMS = pvsffi->dwFileVersionMS;
			*pdwFileVerLS = pvsffi->dwFileVersionLS;
			bRet = TRUE;
		}
	}
	delete [] lpbyteVI;

	return bRet;
}

BOOL DownloadFile(LPCWSTR lpszDatURL, LPCWSTR lpszLocalPath)
{
	BOOL bRet = FALSE;

	WCHAR szPath[1024];
	if (GetFilePath(lpszLocalPath, szPath, sizeof(szPath) / sizeof(WCHAR)) == FALSE)
		return FALSE;

	if (CreateDirectoryW(szPath, NULL) == FALSE && GetLastError() != ERROR_ALREADY_EXISTS)
		return FALSE;

	HMODULE hMod = LoadLibraryW(L"urlmon.dll");
	if (hMod == NULL) 
		return FALSE;

	typedef HRESULT (STDAPICALLTYPE *pfURLDownloadToFile)(LPUNKNOWN,LPCWSTR,LPCWSTR,DWORD,LPBINDSTATUSCALLBACK);
	pfURLDownloadToFile URLDownloadToFile = (pfURLDownloadToFile)GetProcAddress(hMod, "URLDownloadToFileW");
	DeleteUrlCacheEntryW(lpszDatURL);

	if (URLDownloadToFile(NULL, lpszDatURL, lpszLocalPath, 0, NULL) == S_OK)
		bRet = TRUE;
	else
		bRet = FALSE;

	FreeLibrary(hMod);

	return bRet;
}

void UpdateGridModule(w_string _filename, w_string _fileversion, w_string _downloadurl)
{
	BOOL bUpdateFile = FALSE;
	WCHAR szBuffer[1024];
	WCHAR lpszInstalledDir[1024];
	GetCurrentPath(lpszInstalledDir, sizeof(lpszInstalledDir) / sizeof(WCHAR));

	w_string strFilePath = lpszInstalledDir;
	strFilePath = strFilePath + L"\\" + _filename;

	DWORD dwVerMS, dwVerLS;
	if (GetFileVersion(strFilePath.c_str(), &dwVerMS, &dwVerLS))
	{
		WCHAR szVersion[32];
		wsprintfW(szVersion, L"%d.%d.%d.%d", dwVerMS >> 16, dwVerMS & 0x0000ffff, dwVerLS >> 16, dwVerLS & 0x0000ffff);
		if (lstrcmpW(szVersion, _fileversion.c_str()) != 0)
			bUpdateFile = TRUE;
	}
	else
		bUpdateFile = TRUE;

	if (bUpdateFile)
	{
		WCHAR szFilePath[1024];
		WCHAR szTempPath[1024];
		GetFilePath(strFilePath.c_str(), szFilePath, sizeof(szBuffer) / sizeof(WCHAR));
		lstrcatW(szFilePath, L"\\update");
		lstrcpyW(szTempPath, szFilePath);
		lstrcatW(szFilePath, L"\\");
		lstrcatW(szFilePath, GetFileName(strFilePath.c_str()));

		if(DownloadFile(_downloadurl.c_str(), szFilePath))
		{
			CopyFileW(szFilePath, strFilePath.c_str(), FALSE);
			DeleteFileW(szFilePath);
		}
		RemoveDirectoryW(szTempPath);
	}
}